package de.koller.pulsar.scene.eclipse;

import Jama.Matrix;
import de.koller.aframe.util.math.BasicMatrixOp;
import de.koller.aframe.util.math.IFunction2D;
import de.koller.aframe.util.math.SphereUtil;
import de.koller.aframe.util.misc.ColorOperations;
import de.koller.aframe.util.resource.IOLoader;
import de.koller.oceanFramework.gl.util.ImagePreview;
import de.koller.oceanFramework.gl.util.RasterManager;
import de.koller.oceanFramework.math.RVec2;
import de.koller.oceanFramework.math.RVec3;
import de.koller.oceanFramework.util.ColorIntUtil;
import de.koller.pulsar.PNode;
import de.koller.pulsar.scene.IScene;
import java.util.Random;

public class EclipseScene extends PNode implements IScene {
	public final Random RND = new Random();
	public final int WIDTH = 1000, HEIGHT = 1000;

	private RasterManager raster = new RasterManager( WIDTH, HEIGHT );		
	private RasterManager texture = new RasterManager( 32, 32 );

	@Override
	protected void init() {
		super.init();
		
		for( int i = 0; i < texture.getWidth(); i++ )
			for( int y = 0; y < texture.getHeight(); y++ )
				if( i % 2 == 0 )
					texture.setPixel( 0xff_ff0000, i, y );
				else
					texture.setPixel( 0xff_0000ff, i, y );
		ImagePreview.showRaster( texture, 800, 800 );
	}	
	
	@Override
	protected void update( int elapsedTime ) {
		super.update( elapsedTime );
	
		raster.clear( 0xff000000 );
		
		int max = WIDTH * HEIGHT;
		final int mh = 1;
		RVec3 l = new RVec3( 1, .5f, 1 ).normalize();
		Matrix xr = BasicMatrixOp.createXRotation( Math.toRadians( -45 ) );
		Matrix yr = BasicMatrixOp.createYRotation( Math.toRadians( 25 ) );
		Matrix m = xr.times( yr );
						
		for( int x = 0; x < raster.getWidth(); x++ ) {
			for( int y = 0; y < raster.getHeight(); y++ ) {
				int r = 0, g = 0, b = 0;
				
				for( int xi = 0; xi < mh; xi++ )
					for( int yi = 0; yi < mh; yi++ ) {
						IFunction2D s = SphereUtil.INSTANCE;
						float sx = 1f / 495 * (x + ( 1f / mh * xi ) - 500 );
						float sy = 1f / 495 * (y + ( 1f / mh * yi ) - 500 );
						float sz = s.getValue( sx, sy );

						RVec3 n = new RVec3( sx, sy, sz ).normalize();
						if( sz == 0 )
							continue;

						int diffuse = ColorOperations.diffuseLight( l, n, 0xffffffff, 0xffffffff );
						int specular = ColorOperations.specularLight( l, n, new RVec3( 0, 0, 1 ), 0xffffffff, 0xffffff, 60 );

						RVec3 tu = new RVec3( sx, sy, sz );
						tu = BasicMatrixOp.multiply( tu, m );
						
						int c = ColorOperations.lightColor( getTextureColor( tu.x, tu.y, tu.z ), 0xff000000, diffuse, specular );
						r += ColorIntUtil.getRValue( c );
						g += ColorIntUtil.getGValue( c );
						b += ColorIntUtil.getBValue( c );
					}
				
				r /= mh*mh;
				g /= mh*mh;
				b /= mh*mh;
				raster.setPixel( ColorIntUtil.getIntColor( 0xff, r, g, b ), x, y );
			
				int w = x * WIDTH + y;
				if( w % 10 == 0 )
					System.out.println( w + " / " + max );
			}
		}
		
		proot.setSceneFrame( IOLoader.create( raster ) );
	}

	private int getTextureColor( float sx, float sy, float sz ) {
		RVec2 top = new RVec2( sy, 0 );
		RVec2 side = new RVec2( sx, sz );
		float rs = side.getDirection();
		float rt = (float)( 1f / Math.PI * Math.cos( top.getLength() * Math.PI * .5f ) ) * 50;
		
		float fs = 1f / (float)(2f*Math.PI) * rs;
		fs = (int)Math.floor( fs * 300 );
		
		float ft = 0; //(int)Math.floor( rt );

		if( ((ft+1)%2 == 0 && fs%2 == 0) || (ft%2 == 0 && (fs+1)%2 == 0) )
			return 0xffff0000;
		else
			return 0xff0000ff;
	}
	
}
